/* 
 *	Copyright 2014  Yanqing Wu
 *		email: yqwu_yqwu@126.com
 *
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
*/

#pragma once
#include "StdCtrlSkin_BaseElt.h"
#include "StdCtrlSkin_Enums.h"
#include "StdCtrlSkinRow.h"
#include "StdCtrlSkinAttrib.h"
#include "StdCtrlSkinBgCell.h"

#include <fstream>

class CStdCtrlSkinWnd;
class CStdCtrlSkinBg;

class CStdCtrlSkinTable :
	public CStdCtrlSkin_BaseElt
{
protected:
	UINT m_weight;
	CStdCtrlSkin_EnumExpand m_expand;
	UINT m_padx, m_pady;
	std::map<UINT, CStdCtrlSkinRow*> m_row_list;

	std::map<UINT, CStdCtrlSkinAttrib> m_col_attrib_list;

	//	Used for layout
	bool m_layout_table;

	UINT m_rows, m_cols;
	//	points of the grid lines to be placed, when the table
	//	is not enlarged
	std::map<UINT, UINT> m_col_point_list;
	std::map<UINT, UINT> m_row_point_list;
	//	weight of each row/column
	std::map<UINT, UINT> m_col_weight_list;
	std::map<UINT, UINT> m_row_weight_list;
	UINT m_totalweight_row, m_totalweight_col;

	//	Points of the grid lines to show, the table may be enlarged and moved
	std::map<UINT, UINT> m_show_col_point_list;
	std::map<UINT, UINT> m_show_row_point_list;

	//	Back pointer to window
	CStdCtrlSkinWnd* m_pWnd;
	//	Back pointer to bg
	CStdCtrlSkinBg* m_pBg;
	//	Rect of content in this table
	CRect m_rect;

public:
	virtual void InitDataElt(CStdCtrlSkinWnd* pWnd, CStdCtrlSkinBg* pBg);

	CStdCtrlSkinTable(CStdCtrlSkinWnd* pWnd=nullptr);
	//	Create table for layout, it should be in a window def
	CStdCtrlSkinTable(CComPtr<IXMLDOMNode> spNode, CStdCtrlSkinWnd* pWnd);
	//	Create table for bg, it should be in a bg def
	CStdCtrlSkinTable(CComPtr<IXMLDOMNode> spNode, CStdCtrlSkinBg* pBg);

	virtual ~CStdCtrlSkinTable(void);

	CString GetFilePath(void);

	virtual bool IsResizable(CStdCtrlSkin_EnumExpand direction);
	//	Min size of table, including the padx and pady
	virtual CSize GetMinTableSize(void);
	//	Min size of content in this table, not including padx and pady
	virtual CSize GetMinContentSize(void);
	//	Weight value for wnd class to calculate rect for this table
	virtual UINT GetWeight(void);

	virtual void SetRect(CRect rect);

	virtual int GetRowStart(UINT row);
	virtual int GetRowEnd(UINT row);
	virtual int GetColStart(UINT col);
	virtual int GetColEnd(UINT col);

	virtual void GenerateName2Cell(std::map<CString, CStdCtrlSkinCell*>& name2cellList);

#ifdef __DUMPTEST
	virtual void Dump(std::ofstream& fio, CStdCtrlSkin_EnumDump type) override;
#endif

	virtual CStdCtrlSkinAttrib GetColAttrib(UINT col);

	virtual bool IsLayoutTable(void)		{ return m_layout_table; }
	virtual bool IsBgTable(void)			{ return !m_layout_table; }

	//	Draw background bmp
	virtual void Draw(HDC hDC);

protected:
	bool LoadXmlNode(CComPtr<IXMLDOMNode> spNode);
	bool LoadColConfig(CComPtr<IXMLDOMNode> spNode);

	//	After the table is loaded, generate min width for each col,
	//	min height for each row
	bool PostLoading(void);
	virtual void CalculateColPoints(std::map<UINT, std::map<LPARAM, UINT>> extData);
	virtual void CalculateRowPoints(std::map<UINT, std::map<LPARAM, UINT>> extData);

	virtual void CalculateShowPoints(void);

#ifdef __DUMPTEST
	virtual void DumpRect(std::ofstream& fio, CStdCtrlSkin_EnumDump type);
	virtual void DumpMinGrid(std::ofstream& fio, CStdCtrlSkin_EnumDump type);
	virtual void DumpShowGrid(std::ofstream& fio, CStdCtrlSkin_EnumDump type);
#endif
};

